package co.yixiang.modules.system.util;

import cn.hutool.core.util.ObjectUtil;
import co.yixiang.exception.BadRequestException;
import co.yixiang.modules.system.annotation.DictAnno;
import co.yixiang.modules.system.domain.DictDetail;
import co.yixiang.modules.system.util.vo.DifferenceFieldVal;
import co.yixiang.modules.system.util.vo.DifferenceVO;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

@Component
public class BeanUtils {

	private static BeanUtils beanUtils;

	@PostConstruct
	public void init() {
		beanUtils = this;
	}

	/**
	 * 获取两个对象有差异的属性Map集合
	 *
	 * @param oldObj 旧对象
	 * @param newObj 新对象
	 * @param clazz  对比对象的class
	 * @return 修改过的属性map集合, 若没有不一致属性或者两者不是同一类则返回null
	 * map{
	 * 属性名: DifferenceFieldVal{
	 * oldVal : 旧属性,
	 * newVal : 新属性
	 * }
	 * }
	 */
	public static <T> Map<String, DifferenceFieldVal> getDifferenceMap(T oldObj, T newObj, Class<T> clazz) {
		Field[] objFields = clazz.getDeclaredFields();
		Map<String, DifferenceFieldVal> result = Arrays.stream(objFields).map(objField -> getDifferenceVOConvertDictVal(oldObj, newObj, objField)).filter(Objects::nonNull).collect(Collectors.toMap(DifferenceVO::getFieldName, DifferenceVO::getDifferenceFieldVal));
		return result.isEmpty() ? null : result;
	}

	/**
	 * 根据新旧对象获取属性名对应的属性值, 封装为 DifferenceVo类
	 *
	 * @param oldObj   旧对象
	 * @param newObj   新对象
	 * @param objField 属性字段
	 * @param <T>      新旧对象的泛型
	 * @return
	 */
	private static <T> DifferenceVO getDifferenceVOConvertDictVal(T oldObj, T newObj, Field objField) {
		try {
			boolean accessible = objField.isAccessible();
			objField.setAccessible(true);
			String fieldName = objField.getName();
			Object oldVal = objField.get(oldObj);
			Object newVal = objField.get(newObj);
			if ((oldVal == null && newVal == null) || (oldVal != null && oldVal.equals(newVal)) || (newVal != null && newVal.equals(oldVal))) {
				return null;
			}
			objField.setAccessible(accessible);
			return getDifferenceVOConvertDictVal(objField, fieldName, oldVal, newVal);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException("无访问权限");
		}
	}

	/**
	 * 获取两个对象有差异的属性JSON
	 *
	 * @param oldObj 旧对象
	 * @param newObj 新对象
	 * @param clazz  对比对象的class
	 * @return 修改过的属性JSON串, 若没有不一致属性或者两者不是同一类则返回null
	 * data {
	 * 属性名: {
	 * oldVal : 旧属性,
	 * newVal : 新属性
	 * }
	 * }
	 */
	public static <T> String getDifferenceJson(T oldObj, T newObj, Class<T> clazz) {
		Map<String, DifferenceFieldVal> differenceMap = getDifferenceMap(oldObj, newObj, clazz);
		return differenceMap == null ? null : JSON.toJSONString(differenceMap);
	}


	/**
	 * description:判断当前对象是否为空
	 * 可选则在判断规则中剔除某一字段，或者某一值
	 *
	 * @param object           入参对象
	 * @param checkBlank       是否判断空串
	 * @param excludeNameList  要剔除的属性名称,没有就传空集合或者null
	 * @param excludeValueList 要剔除的数值,没有就传空集合或者null
	 * @return boolean
	 * @author ZhangXihui
	 **/
	private static boolean objCheckIsNull(Object object, boolean checkBlank, List<String> excludeNameList, List<?> excludeValueList) throws IllegalAccessException {
		if (object == null) {
			return true;
		}
		// 得到类对象
		Class<?> clazz = object.getClass();
		// 得到所有属性
		Field[] fields = clazz.getDeclaredFields();
		//判断入参
		boolean excludeNameListFlag = false;
		if (excludeNameList != null && excludeNameList.size() > 0) {
			excludeNameListFlag = true;
		}
		boolean excludeValueListFlag = false;
		if (excludeValueList != null && excludeValueList.size() > 0) {
			excludeValueListFlag = true;
		}
		//定义返回结果，默认为true
		boolean flag = true;
		for (Field field : fields) {
			field.setAccessible(true);

			//得到属性类型
			Type fieldType = field.getGenericType();
			String typeName = fieldType.getTypeName();

			//得到属性值
			Object fieldValue = field.get(object);

			//得到属性名
			String fieldName = field.getName();
			//剔除指定属性名的属性值
			if (excludeNameListFlag) {
				boolean exclude = excludeNameList.stream().anyMatch(fieldName::equals);
				if (exclude) {
					fieldValue = null;
				}
			}
			//剔除指定属性值
			if (fieldValue != null && excludeValueListFlag) {
				boolean exclude = excludeValueList.stream().anyMatch(fieldValue::equals);
				if (exclude) {
					fieldValue = null;
				}
			}

			//只要有一个属性值不为null 就返回false 表示对象不为null 忽略序列化
			boolean check = checkBlank ? !"serialVersionUID".equals(fieldName) && fieldValue != null && !"".equals(fieldValue) : !"serialVersionUID".equals(fieldName) && fieldValue != null;
			if (check) {
				flag = false;
				break;
			}
		}
		return flag;
	}

	/**
	 * description:判断当前对象是否为空（所有属性为null）
	 *
	 * @param object 入参对象
	 * @return boolean
	 * @author ZhangXihui
	 **/
	public static boolean objCheckIsNull(Object object) throws IllegalAccessException {
		return objCheckIsNull(object, false, null, null);
	}

	/**
	 * description:判断当前对象是否为空（所有属性为null）
	 *
	 * @param excludeValueList 判断排除属性值集合 (值为集合中的数据则跳过判断)
	 * @param object           入参对象
	 * @return boolean
	 **/
	public static boolean objCheckIsNull(List<?> excludeValueList, Object object) throws IllegalAccessException {
		return objCheckIsNull(object, false, null, excludeValueList);
	}

	/**
	 * description:判断当前对象是否为空（所有属性为null）
	 *
	 * @param object          入参对象
	 * @param excludeNameList 判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsNull(Object object, List<String> excludeNameList) throws IllegalAccessException {
		return objCheckIsNull(object, false, excludeNameList, null);
	}

	/**
	 * description:判断当前对象是否为空（所有属性为null）
	 *
	 * @param object           入参对象
	 * @param excludeNameList  判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @param excludeValueList 判断排除属性值集合 (属性值为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsNull(Object object, List<String> excludeNameList, List<Object> excludeValueList) throws IllegalAccessException {
		return objCheckIsNull(object, false, excludeNameList, excludeValueList);
	}

	/**
	 * description:判断当前对象是否为空（包括所有属性为null, 和字符串为null或空串）
	 *
	 * @param object 入参对象
	 * @return boolean
	 * @author ZhangXihui
	 **/
	public static boolean objCheckIsBlank(Object object) throws IllegalAccessException {
		return objCheckIsNull(object, true, null, null);
	}

	/**
	 * description:判断当前对象是否为空（包括所有属性为null, 和字符串为null或空串）
	 *
	 * @param excludeValueList 判断排除属性值集合 (值为集合中的数据则跳过判断)
	 * @param object           入参对象
	 * @return boolean
	 **/
	public static boolean objCheckIsBlank(List<?> excludeValueList, Object object) throws IllegalAccessException {
		return objCheckIsNull(object, true, null, excludeValueList);
	}

	/**
	 * description:判断当前对象是否为空（包括所有属性为null, 和字符串为null或空串）
	 *
	 * @param object          入参对象
	 * @param excludeNameList 判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsBlank(Object object, List<String> excludeNameList) throws IllegalAccessException {
		return objCheckIsNull(object, true, excludeNameList, null);
	}

	/**
	 * description:判断当前对象是否为空（包括所有属性为null, 和字符串为null或空串）
	 *
	 * @param object           入参对象
	 * @param excludeNameList  判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @param excludeValueList 判断排除属性值集合 (属性值为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsBlank(Object object, List<String> excludeNameList, List<Object> excludeValueList) throws IllegalAccessException {
		return objCheckIsNull(object, true, excludeNameList, excludeValueList);
	}

	/**
	 * description:判断当前对象是否不为空（所有属性不为null）
	 *
	 * @param object 入参对象
	 * @return boolean
	 * @author ZhangXihui
	 **/
	public static boolean objCheckIsNotNull(Object object) throws IllegalAccessException {
		return !objCheckIsNull(object, false, null, null);
	}

	/**
	 * description:判断当前对象是否不为空（所有属性不为null）
	 *
	 * @param excludeValueList 判断排除属性值集合 (值为集合中的数据则跳过判断)
	 * @param object           入参对象
	 * @return boolean
	 **/
	public static boolean objCheckIsNotNull(List<?> excludeValueList, Object object) throws IllegalAccessException {
		return !objCheckIsNull(object, false, null, excludeValueList);
	}

	/**
	 * description:判断当前对象是否不为空（所有属性不为null）
	 *
	 * @param object          入参对象
	 * @param excludeNameList 判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsNotNull(Object object, List<String> excludeNameList) throws IllegalAccessException {
		return !objCheckIsNull(object, false, excludeNameList, null);
	}

	/**
	 * description:判断当前对象是否不为空（所有属性不为null）
	 *
	 * @param object           入参对象
	 * @param excludeNameList  判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @param excludeValueList 判断排除属性值集合 (属性值为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsNotNull(Object object, List<String> excludeNameList, List<Object> excludeValueList) throws IllegalAccessException {
		return !objCheckIsNull(object, false, excludeNameList, excludeValueList);
	}

	/**
	 * description:判断当前对象是否不为空（包括所有属性不为 null , 和字符串不为 null 和 空串）
	 *
	 * @param object 入参对象
	 * @return boolean
	 * @author ZhangXihui
	 **/
	public static boolean objCheckIsNotBlank(Object object) throws IllegalAccessException {
		return !objCheckIsNull(object, true, null, null);
	}

	/**
	 * description:判断当前对象是否不为空（包括所有属性不为 null , 和字符串不为 null 和 空串）
	 *
	 * @param excludeValueList 判断排除属性值集合 (值为集合中的数据则跳过判断)
	 * @param object           入参对象
	 * @return boolean
	 **/
	public static boolean objCheckIsNotBlank(List<?> excludeValueList, Object object) throws IllegalAccessException {
		return !objCheckIsNull(object, true, null, excludeValueList);
	}

	/**
	 * description:判断当前对象是否不为空（包括所有属性不为 null , 和字符串不为 null 和 空串）
	 *
	 * @param object          入参对象
	 * @param excludeNameList 判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsNotBlank(Object object, List<String> excludeNameList) throws IllegalAccessException {
		return !objCheckIsNull(object, true, excludeNameList, null);
	}

	/**
	 * description:判断当前对象是否不为空（包括所有属性不为 null , 和字符串不为 null 和 空串）
	 *
	 * @param object           入参对象
	 * @param excludeNameList  判断排除属性名集合 (属性名为集合中的数据则跳过判断)
	 * @param excludeValueList 判断排除属性值集合 (属性值为集合中的数据则跳过判断)
	 * @return boolean
	 **/
	public static boolean objCheckIsNotBlank(Object object, List<String> excludeNameList, List<Object> excludeValueList) throws IllegalAccessException {
		return !objCheckIsNull(object, true, excludeNameList, excludeValueList);
	}


	/**
	 * 获取两个对象有差异的属性List集合
	 *
	 * @param oldObj      旧对象
	 * @param newObj      新对象
	 * @param clazz       对比对象的class
	 * @param excludeList 排除属性名称
	 * @param checkSuper  是否比较父类属性
	 * @return 修改过的属性list集合, 若没有不一致属性或者两者不是同一类则返回null
	 */
	public static <T> List<DifferenceVO> getDifferenceList(T oldObj, T newObj, Class<? super T> clazz, List<String> excludeList, boolean checkSuper) {
		List<Field> fieldList = checkSuper ? getFields(clazz) : Arrays.asList(clazz.getDeclaredFields());
		List<DifferenceVO> result = fieldList.stream().map(objField -> getDifferenceVOConvertDictVal(oldObj, newObj, objField, excludeList)).filter(Objects::nonNull).collect(Collectors.toList());
		return result.isEmpty() ? null : result;
	}


	/**
	 * 根据新旧对象获取属性名对应的属性值, 封装为 DifferenceVo类
	 *
	 * @param oldObj   旧对象
	 * @param newObj   新对象
	 * @param objField 属性字段
	 * @param <T>      新旧对象的泛型
	 * @return 新旧对象获取属性名对应的属性值
	 */
	private static <T> DifferenceVO getDifferenceVOConvertDictVal(T oldObj, T newObj, Field objField, List<String> excludeList) {
		try {
			objField.setAccessible(true);
			String fieldName = objField.getName();
			Object oldVal = objField.get(oldObj);
			Object newVal = objField.get(newObj);
			if ((excludeList != null && excludeList.contains(fieldName)) || (oldVal == null && newVal == null) || (oldVal != null && oldVal.equals(newVal)) || (newVal != null && newVal.equals(oldVal))) {
				return null;
			}

			return getDifferenceVOConvertDictVal(objField, fieldName, oldVal, newVal);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new RuntimeException("无访问权限");
		}
	}

	/**
	 * 获取对比差异数据, 并转换字典属性
	 * @param objField 字段对象
	 * @param fieldName 字段名称
	 * @param oldVal 旧数据
	 * @param newVal 新数据
	 * @return 差异数据
	 */
	private static DifferenceVO getDifferenceVOConvertDictVal(Field objField, String fieldName, Object oldVal, Object newVal) {
		DictAnno dictAnno = objField.getAnnotation(DictAnno.class);

		if (dictAnno != null) {
			String dictType = dictAnno.value();

			if (StringUtils.isNotBlank(dictType)) {
				List<DictDetail> byDictType = DictUtils.findByDictType(dictType);

				String oldValStr = Objects.toString(oldVal, "");
				String newValStr = Objects.toString(newVal, "");

				oldVal = byDictType.stream().filter(o -> o.getLabel().equals(oldValStr)).map(DictDetail::getValue).findFirst().orElse(null);
				newVal = byDictType.stream().filter(o -> o.getLabel().equals(newValStr)).map(DictDetail::getValue).findFirst().orElse(null);
			}
		}
		DifferenceFieldVal field = DifferenceFieldVal.builder().newVal(newVal).oldVal(oldVal).build();
		return DifferenceVO.builder().fieldName(fieldName).differenceFieldVal(field).build();
	}

	/**
	 * 获取两个对象有差异的属性List集合
	 *
	 * @param oldObj      旧对象
	 * @param newObj      新对象
	 * @param clazz       对比对象的class
	 * @param excludeList 排除属性名称
	 * @return 修改过的属性list集合, 若没有不一致属性或者两者不是同一类则返回null
	 */
	public static <T> List<DifferenceVO> getDifferenceList(T oldObj, T newObj, Class<? super T> clazz, List<String> excludeList) {
		return getDifferenceList(oldObj, newObj, clazz, excludeList, true);
	}

	/**
	 * 获取两个对象有差异的属性Map集合
	 *
	 * @param oldObj      旧对象
	 * @param newObj      新对象
	 * @param clazz       对比对象的class
	 * @param excludeList 排除属性名称
	 * @return 修改过的属性map集合, 若没有不一致属性或者两者不是同一类则返回null
	 * map{
	 * 属性名: DifferenceFieldVal{
	 * oldVal : 旧属性,
	 * newVal : 新属性
	 * }
	 * }
	 */
	public static <T> Map<String, DifferenceFieldVal> getDifferenceMap(T oldObj, T newObj, Class<T> clazz, List<String> excludeList) {
		List<Field> fieldList = getFields(clazz);
		Map<String, DifferenceFieldVal> result = fieldList.stream().map(objField -> getDifferenceVOConvertDictVal(oldObj, newObj, objField, excludeList)).filter(Objects::nonNull).collect(Collectors.toMap(DifferenceVO::getFieldName, DifferenceVO::getDifferenceFieldVal));
		return result.isEmpty() ? null : result;
	}

	/**
	 * 获取两个对象有差异map集合的属性JSON
	 *
	 * @param oldObj 旧对象
	 * @param newObj 新对象
	 * @param clazz  对比对象的class
	 * @return 修改过的属性JSON串, 若没有不一致属性或者两者不是同一类则返回null
	 * data {
	 * 属性名: {
	 * oldVal : 旧属性,
	 * newVal : 新属性
	 * }
	 * }
	 */
	public static <T> String getDifferenceMapJson(T oldObj, T newObj, Class<T> clazz) {
		Map<String, DifferenceFieldVal> differenceMap = getDifferenceMap(oldObj, newObj, clazz, null);
		return differenceMap == null ? null : JSON.toJSONString(differenceMap);
	}

	/**
	 * 获取两个对象有差异的属性JSON
	 *
	 * @param oldObj      旧对象
	 * @param newObj      新对象
	 * @param clazz       对比对象的class
	 * @param excludeList 排除属性名称
	 * @return 修改过的属性JSON串, 若没有不一致属性或者两者不是同一类则返回null
	 * data {
	 * 属性名: {
	 * oldVal : 旧属性,
	 * newVal : 新属性
	 * }
	 * }
	 */
	public static <T> String getDifferenceMapJson(T oldObj, T newObj, Class<T> clazz, List<String> excludeList) {
		Map<String, DifferenceFieldVal> differenceMap = getDifferenceMap(oldObj, newObj, clazz, excludeList);
		return differenceMap == null ? null : JSON.toJSONString(differenceMap);
	}

	/**
	 * 获取两个对象有差异list集合的属性JSON
	 *
	 * @param oldObj 旧对象
	 * @param newObj 新对象
	 * @param clazz  对比对象的class
	 * @return 修改过的属性JSON串, 若没有不一致属性或者两者不是同一类则返回null
	 */
	public static <T> String getDifferenceListJson(T oldObj, T newObj, Class<T> clazz) {
		Map<String, DifferenceFieldVal> differenceMap = getDifferenceMap(oldObj, newObj, clazz, null);
		return differenceMap == null ? null : JSON.toJSONString(differenceMap);
	}

	/**
	 * 获取两个对象有差异list集合的属性JSON
	 *
	 * @param oldObj      旧对象
	 * @param newObj      新对象
	 * @param clazz       对比对象的class
	 * @param excludeList 排除属性名称
	 * @return 修改过的属性JSON串, 若没有不一致属性或者两者不是同一类则返回null
	 */
	public static <T> String getDifferenceListJson(T oldObj, T newObj, Class<T> clazz, List<String> excludeList) {
		Map<String, DifferenceFieldVal> differenceMap = getDifferenceMap(oldObj, newObj, clazz, excludeList);
		return differenceMap == null ? null : JSON.toJSONString(differenceMap);
	}

	private static List<Field> getFields(Class<?> clazz) {
		List<Field> fieldList = new ArrayList<>();
		while (clazz != null && !clazz.getName().toLowerCase().equals("java.lang.object")) {//当父类为null的时候说明到达了最上层的父类(Object类).
			fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
			clazz = clazz.getSuperclass(); //得到父类,然后赋给自己
		}
		return fieldList;
	}


	public static void isTrue(boolean flag, String message) {
		if (!flag)
			throw new BadRequestException(message);
	}


	public static void isTrue(boolean flag) {
		isTrue(flag, "");
	}

	public static <T> T notEmpty(T data, String msg) {
		if (ObjectUtil.isEmpty(data)) {
			throw new BadRequestException(msg);
		}
		return data;
	}

	public static <T> T notEmpty(T data) {
		return notEmpty(data, "参数异常, 参数为空");
	}

	public static <T> T isEmpty(T data, String msg) {
		if (ObjectUtil.isNotEmpty(data)) {
			throw new BadRequestException(msg);
		}
		return data;
	}

	public static <T> T isEmpty(T data) {
		return isEmpty(data, "参数异常, 参数为空");
	}

	/**
	 * 判断对象是否为空 为空则抛异常
	 *
	 * @param obj     校验对象
	 * @param message 异常信息
	 * @param <T> 校验对象泛型
	 * @return 校验对象
	 */
	public static <T> T notNull(T obj, String message) {
		if (obj == null)
			throw new BadRequestException(StringUtils.isBlank(message) ? "参数异常, 参数为空" : message);
		return obj;
	}

	/**
	 * 判断对象是否为空 为空则抛异常
	 *
	 * @param obj     校验对象
	 * @param c 异常信息
	 * @param <T> 校验对象泛型
	 * @return 校验对象
	 */
	public static <T> T notNull(T obj, Supplier<String> c) {
		if (obj == null) {
			throw new BadRequestException(c.get());
		}
		return obj;
	}

	/**
	 * 判断对象是否为空 为空则抛异常
	 *
	 * @param obj 校验对象
	 * @param <T>
	 * @return 校验对象
	 */
	public static <T> T notNull(T obj) {
		return notNull(obj, () -> "参数异常, 参数为空");
	}

	/**
	 * 判断字符串是否为空 不为空则抛异常
	 *
	 * @param str     校验对象
	 * @param message 异常信息
	 * @return 校验对象
	 */
	public static String isBlank(String str, String message) {
		if (StringUtils.isNotBlank(str))
			throw new BadRequestException(StringUtils.isBlank(message) ? "参数异常, 参数为空" : message);
		return str;
	}

	/**
	 * 判断字符串是否为空 不为空则抛异常
	 *
	 * @param str 校验对象
	 * @return 校验对象
	 */
	public static String isBlank(String str) {
		return isBlank(str, null);
	}

	/**
	 * 判断字符串是否不为空 为空则抛异常
	 *
	 * @param str     校验对象
	 * @param message 异常信息
	 * @return 校验对象
	 */
	public static String notBlank(String str, String message) {
		if (StringUtils.isBlank(str))
			throw new BadRequestException(StringUtils.isBlank(message) ? "参数异常, 参数为空" : message);
		return str;
	}

	/**
	 * 判断字符串是否不为空 为空则抛异常
	 *
	 * @param str     校验对象
	 * @return 校验对象
	 */
	public static String notBlank(String str) {
		return notBlank(str,null);
	}

	/**
	 * 校验对象是否为空, 若为空测返回默认对象
	 *
	 * @param obj          校验对象
	 * @param defaultValue 默认对象
	 * @param <T>
	 * @return
	 */
	public static <T> T defaultIfNull(T obj, T defaultValue) {
		return obj == null ? defaultValue : obj;
	}

	/**
	 * 获取List中的某个数据
	 * @param dataList 转换List
	 * @param valFunc value
	 * @param <V> value的返回类型
	 * @param <T> 转换对象数据类型
	 * @return 数据对象List
	 */
	public static <V, T> List<V> listToFiled(List<T> dataList, Function<T, V> valFunc) {
		if (ObjectUtil.isEmpty(dataList)) {
			return Lists.newArrayList();
		}
		return dataList.stream().map(valFunc).collect(Collectors.toList());
	}

	/**
	 * List转Map
	 * @param dataList 转换List
	 * @param keyFunc key
	 * @param <K> key的返回类型
	 * @param <T> 转换对象数据类型
	 * @return 转换后的map Value为本身
	 */
	public static <K, T> Map<K, T> listToMap(List<T> dataList, Function<T, K> keyFunc) {
		return listToMap(dataList, keyFunc, t -> t);
	}

	/**
	 * List转Map
	 * @param dataList 转换List
	 * @param keyFunc key
	 * @param valFunc value
	 * @param <K> key的返回类型
	 * @param <V> value的返回类型
	 * @param <T> 转换对象数据类型
	 * @return 转换后的map
	 */
	public static <K, V, T> Map<K, V> listToMap(List<T> dataList, Function<T, K> keyFunc, Function<T, V> valFunc) {
		if (ObjectUtil.isEmpty(dataList)) {
			return Maps.newHashMap();
		}
		return dataList.stream().collect(Collectors.toMap(keyFunc, valFunc));
	}

	/**
	 * 数组转Map
	 * @param dataArr 转换数组
	 * @param keyFunc key
	 * @param <K> key的返回类型
	 * @param <T> 转换对象数据类型
	 * @return 转换后的map Value为本身
	 */
	public static <K, T> Map<K, T> arrToMap(T[] dataArr, Function<T, K> keyFunc) {
		return arrToMap(dataArr, keyFunc, t -> t);
	}

	/**
	 * 数组转Map
	 * @param dataArr 转换数组
	 * @param keyFunc key
	 * @param valFunc value
	 * @param <K> key的返回类型
	 * @param <V> value的返回类型
	 * @param <T> 转换对象数据类型
	 * @return 转换后的map
	 */
	public static <K, V, T> Map<K, V> arrToMap(T[] dataArr, Function<T, K> keyFunc, Function<T, V> valFunc) {
		if (ObjectUtil.isEmpty(dataArr)) {
			return Maps.newHashMap();
		}
		return Arrays.stream(dataArr).collect(Collectors.toMap(keyFunc, valFunc));
	}
}